package com.djf.controller;

import com.djf.entity.Order;
import com.djf.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单控制器
 * 
 * @author djf
 * @since 2024-01-20
 */
@Slf4j
@RestController
@RequestMapping("/api/orders")
@RequiredArgsConstructor
public class OrderController {

    private final OrderService orderService;

    /**
     * 创建订单
     * 
     * @param order 订单信息
     * @return 创建结果
     */
    @PostMapping
    public Map<String, Object> createOrder(@RequestBody Order order) {
        Map<String, Object> result = new HashMap<>();
        try {
            Order createdOrder = orderService.createOrder(order);
            result.put("success", true);
            result.put("message", "订单创建成功");
            result.put("data", createdOrder);
            log.info("订单创建成功：{}", createdOrder.getOrderNo());
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "订单创建失败：" + e.getMessage());
            log.error("订单创建失败", e);
        }
        return result;
    }

    /**
     * 根据用户ID查询订单
     * 
     * @param userId 用户ID
     * @return 订单列表
     */
    @GetMapping("/user/{userId}")
    public Map<String, Object> getOrdersByUserId(@PathVariable Long userId) {
        Map<String, Object> result = new HashMap<>();
        try {
            List<Order> orders = orderService.getOrdersByUserId(userId);
            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", orders);
            result.put("count", orders.size());
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "查询失败：" + e.getMessage());
            log.error("查询订单失败", e);
        }
        return result;
    }

    /**
     * 根据租户ID查询订单
     * 
     * @param tenantId 租户ID
     * @return 订单列表
     */
    @GetMapping("/tenant/{tenantId}")
    public Map<String, Object> getOrdersByTenantId(@PathVariable Long tenantId) {
        Map<String, Object> result = new HashMap<>();
        try {
            List<Order> orders = orderService.getOrdersByTenantId(tenantId);
            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", orders);
            result.put("count", orders.size());
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "查询失败：" + e.getMessage());
            log.error("查询订单失败", e);
        }
        return result;
    }

    /**
     * 根据时间范围查询订单
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 订单列表
     */
    @GetMapping("/time-range")
    public Map<String, Object> getOrdersByTimeRange(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> result = new HashMap<>();
        try {
            List<Order> orders = orderService.getOrdersByTimeRange(startTime, endTime);
            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", orders);
            result.put("count", orders.size());
            log.info("时间范围查询：{} - {}，结果数量：{}", startTime, endTime, orders.size());
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "查询失败：" + e.getMessage());
            log.error("查询订单失败", e);
        }
        return result;
    }

    /**
     * 根据用户ID和时间范围查询订单
     * 
     * @param userId 用户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 订单列表
     */
    @GetMapping("/user/{userId}/time-range")
    public Map<String, Object> getOrdersByUserIdAndTimeRange(
            @PathVariable Long userId,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> result = new HashMap<>();
        try {
            List<Order> orders = orderService.getOrdersByUserIdAndTimeRange(userId, startTime, endTime);
            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", orders);
            result.put("count", orders.size());
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "查询失败：" + e.getMessage());
            log.error("查询订单失败", e);
        }
        return result;
    }

    /**
     * 更新订单状态
     * 
     * @param orderId 订单ID
     * @param orderStatus 订单状态
     * @return 更新结果
     */
    @PutMapping("/{orderId}/status")
    public Map<String, Object> updateOrderStatus(@PathVariable Long orderId, @RequestParam Integer orderStatus) {
        Map<String, Object> result = new HashMap<>();
        try {
            boolean success = orderService.updateOrderStatus(orderId, orderStatus);
            result.put("success", success);
            result.put("message", success ? "状态更新成功" : "状态更新失败");
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "状态更新失败：" + e.getMessage());
            log.error("更新订单状态失败", e);
        }
        return result;
    }

    /**
     * 统计指定时间范围内的订单数量
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计结果
     */
    @GetMapping("/count")
    public Map<String, Object> countOrdersByTimeRange(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long count = orderService.countOrdersByTimeRange(startTime, endTime);
            result.put("success", true);
            result.put("message", "统计成功");
            result.put("count", count);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "统计失败：" + e.getMessage());
            log.error("统计订单失败", e);
        }
        return result;
    }

    /**
     * 生成测试数据
     * 
     * @param count 生成数量
     * @return 生成结果
     */
    @PostMapping("/test-data")
    public Map<String, Object> generateTestData(@RequestParam(defaultValue = "20") int count) {
        Map<String, Object> result = new HashMap<>();
        try {
            List<Order> orders = orderService.generateTestData(count);
            result.put("success", true);
            result.put("message", "测试数据生成成功");
            result.put("data", orders);
            result.put("count", orders.size());
            log.info("生成测试数据成功，数量：{}", count);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "测试数据生成失败：" + e.getMessage());
            log.error("生成测试数据失败", e);
        }
        return result;
    }

    /**
     * 获取分表信息
     * 
     * @return 分表信息
     */
    @GetMapping("/sharding-info")
    public Map<String, Object> getShardingInfo() {
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "分表信息");
        
        Map<String, Object> shardingInfo = new HashMap<>();
        shardingInfo.put("shardingStrategy", "按时间分表（年月）");
        shardingInfo.put("shardingColumn", "create_time");
        shardingInfo.put("tablePattern", "order_yyyyMM");
        shardingInfo.put("availableTables", new String[]{"order_202401", "order_202402", "order_202403", "order_202404", "order_202405", "order_202406", "order_202407", "order_202408", "order_202409", "order_202410", "order_202411", "order_202412"});
        
        result.put("data", shardingInfo);
        return result;
    }


    /**
     * 触发运行时异常
     *
     * @return 响应结果
     */
    @GetMapping("/trigger-runtime-exception")
    public Map<String, Object> triggerRuntimeException() {
        throw new RuntimeException("这是一个运行时异常");
    }

    /**
     * 触发空指针异常
     *
     * @return 响应结果
     */
    @GetMapping("/trigger-null-pointer-exception")
    public Map<String, Object> triggerNullPointerException() {
        String value = null;
        value.length(); // 触发空指针异常
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", "此行不会执行");
        return response;
    }

    /**
     * 触发非法参数异常
     *
     * @param number 参数
     * @return 响应结果
     */
    @GetMapping("/trigger-illegal-argument-exception")
    public Map<String, Object> triggerIllegalArgumentException(@RequestParam int number) {
        if (number < 0) {
            throw new IllegalArgumentException("数字不能为负数");
        }
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", "参数有效");
        return response;
    }
}